package com.liyunc.demo.detect.camera;

import com.liyunc.demo.detect.service.DetectService;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;

import javax.swing.JFrame;

/**
 * 检测人脸并保存到硬盘的服务.
 * 为训练模型提供资源.
 */
public class PreviewCameraWithDetectAndSave extends AbstractCameraApplication {

    // 展示帧的本地窗口
    protected CanvasFrame previewCanvas;

    // 检测工具接口
    private final DetectService detectService;

    /**
     * 构造方法，不同的检测工具，可通过构造方法传入.
     *
     * @param detectService 检测工具接口
     */
    public PreviewCameraWithDetectAndSave(DetectService detectService) {
        this.detectService = detectService;
    }

    /**
     * 初始化操作.
     */
    @Override
    protected void initOutput() throws Exception {
        previewCanvas = new CanvasFrame("camera preview,detect and save",
                CanvasFrame.getDefaultGamma() / grabber.getGamma());
        previewCanvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        previewCanvas.setAlwaysOnTop(true);

        // 检测服务的初始话操作
        detectService.init();
    }

    /**
     * 检测人脸并保存图片.
     *
     * @param frame 原始帧
     */
    @Override
    protected void output(Frame frame) throws Exception {
        // 原始帧先交给检测服务处理，这个处理包括物体检测，再将检测结果标注在原始图片上，
        // 然后转换为帧返回
        Frame detectedFrame = detectService.convert(frame);
        // 预览窗口上显示的帧是标注了检测结果的帧，处理之后的帧
        previewCanvas.showImage(detectedFrame);
    }

    /**
     * 释放检测服务占用的资源.
     */
    @Override
    protected void releaseOutputResource() throws Exception {
        if (null != previewCanvas) {
            previewCanvas.dispose();
        }
        // 检测工具也要释放资源
        detectService.releaseResource();
    }

    /**
     * 由于检测服务有耗时操作，帧间隔要低于普通预览.
     *
     * @return 帧间隔时间（秒）
     */
    @Override
    protected int getInterval() {
        final int i = 8;
        return super.getInterval() / i;
    }
}
